package com.dagger.controller;

import java.io.IOException;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.springframework.stereotype.Component;

import com.alibaba.fastjson2.JSON;
import com.dagger.config.MsgConfig;
import com.dagger.constants.LocalErrorCode;
import com.dagger.domain.req.WsMsgReq;
import com.dagger.domain.resp.MsgResponse;
import com.dagger.utils.AbstractMsgUtil;
import com.dagger.utils.LocalBeanUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 通用websocket接口
 * 
 * @author dagger
 *
 */
@ServerEndpoint("/ws/common")
@Component
@Slf4j
public class WebSocketServer {

	/**
	 * 建立WebSocket连接
	 *
	 * @param session session
	 */
	@OnOpen
	public void onOpen(Session session) {
		log.info("WebSocket连接建立成功");
		AbstractMsgUtil.getWebsocketUtil().addUser(session);
		AbstractMsgUtil.getWebsocketUtil().sendMessage(session, MsgResponse.newSuccessMessage("连接成功"));
	}

	/**
	 * 发生错误
	 *
	 * @param throwable e
	 */
	@OnError
	public void onError(Session session, Throwable throwable) {
		log.error("WebSocket连接出现异常");
		try {
			AbstractMsgUtil.getWebsocketUtil().removeUser(session);
			session.close();
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		} finally {
			// 删除映射关系
			onClose(session);
		}
		log.error(throwable.getLocalizedMessage(), throwable);
	}

	/**
	 * 连接关闭
	 */
	@OnClose
	public void onClose(Session session) {
		log.info("WebSocket连接关闭");
		AbstractMsgUtil.getWebsocketUtil().removeUser(session);
	}

	/**
	 * 接收客户端消息
	 *
	 * @param message 接收的消息
	 */
	@OnMessage
	public void onMessage(Session session, String message) {
		log.info("收到客户端[{}]发来的消息：{}", session.getId(), message);
		WsMsgReq inputWsMsg;
		try {
			inputWsMsg = JSON.parseObject(message, WsMsgReq.class);
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
			AbstractMsgUtil.getWebsocketUtil().sendMessage(session,
					MsgResponse.newFailedMessage(LocalErrorCode.MSG_INPUT_ERROR_CONTENT));
			return;
		}

		if (LocalBeanUtils.isSomeOneEmpty(inputWsMsg.getMsgType(), inputWsMsg.getMsgOption(), inputWsMsg.getBussinessType(),
				inputWsMsg.getBussinessId())) {
			AbstractMsgUtil.getWebsocketUtil().sendMessage(session,
					MsgResponse.newFailedMessage(LocalErrorCode.MSG_INPUT_EMPTY_CONTENT));
			return;
		}

		switch (inputWsMsg.getMsgOption()) {
		case SUBSCRIBE: {
			if (!MsgConfig.getInstance().contains(inputWsMsg.getBussinessType())) {
				AbstractMsgUtil.getWebsocketUtil().sendMessage(session,
						MsgResponse.newFailedMessage(LocalErrorCode.MSG_NOT_SUPPORT));
			}

			switch (inputWsMsg.getMsgType()) {
			case DELAY: {
				AbstractMsgUtil.getWebsocketUtil().subcribeDelayMsg(session, inputWsMsg.getBussinessType(),
						inputWsMsg.getBussinessId());				
				break;
			}
			case REALTIME: {
				AbstractMsgUtil.getWebsocketUtil().subcribeRealtimeMsg(session, inputWsMsg.getBussinessType(),
						inputWsMsg.getBussinessId());
				break;
			}
			default:
				AbstractMsgUtil.getWebsocketUtil().sendMessage(session,
						MsgResponse.newFailedMessage(LocalErrorCode.MSG_NOT_SUPPORT));
				break;
			}

			break;
		}
		case UNSUBSCRIBE: {
			AbstractMsgUtil.getWebsocketUtil().unSubcribeMsg(session, inputWsMsg.getBussinessType(),
					inputWsMsg.getBussinessId());
			break;
		}
		}

	}
}
